using ICSharpCode.TextEditor.Actions;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace ICSharpCode.TextEditor
{
    [ToolboxItem(false)]
    public class TextArea : Control
    {
        private bool hiddenMouseCursor;
        private Point mouseCursorHidePosition;
        private Point virtualTop = new Point(0, 0);
        private TextAreaControl motherTextAreaControl;
        private TextEditorControl motherTextEditorControl;
        private List<BracketHighlightingSheme> bracketshemes = new List<BracketHighlightingSheme>();
        private TextAreaClipboardHandler textAreaClipboardHandler;
        private bool autoClearSelection;
        private List<AbstractMargin> leftMargins = new List<AbstractMargin>();
        private TextView textView;
        private GutterMargin gutterMargin;
        private FoldMargin foldMargin;
        private IconBarMargin iconBarMargin;
        private SelectionManager selectionManager;
        private Caret caret;
        internal Point mousepos = new Point(0, 0);
        private bool disposed;
        private AbstractMargin lastMouseInMargin;
        private static DeclarationViewWindow toolTip;
        private static string oldToolTip;
        private bool toolTipActive;
        private Rectangle toolTipRectangle;
        private AbstractMargin updateMargin;
        public event ToolTipRequestEventHandler ToolTipRequest;
        public event KeyEventHandler KeyEventHandler;
        public event DialogKeyProcessor DoProcessDialogKey;
        [Browsable(false)]
        public IList<AbstractMargin> LeftMargins
        {
            get
            {
                return this.leftMargins.AsReadOnly();
            }
        }
        public TextEditorControl MotherTextEditorControl
        {
            get
            {
                return this.motherTextEditorControl;
            }
        }
        public TextAreaControl MotherTextAreaControl
        {
            get
            {
                return this.motherTextAreaControl;
            }
        }
        public SelectionManager SelectionManager
        {
            get
            {
                return this.selectionManager;
            }
        }
        public Caret Caret
        {
            get
            {
                return this.caret;
            }
        }
        public TextView TextView
        {
            get
            {
                return this.textView;
            }
        }
        public GutterMargin GutterMargin
        {
            get
            {
                return this.gutterMargin;
            }
        }
        public FoldMargin FoldMargin
        {
            get
            {
                return this.foldMargin;
            }
        }
        public IconBarMargin IconBarMargin
        {
            get
            {
                return this.iconBarMargin;
            }
        }
        public Encoding Encoding
        {
            get
            {
                return this.motherTextEditorControl.Encoding;
            }
        }
        public int MaxVScrollValue
        {
            get
            {
                return (this.Document.GetVisibleLine(this.Document.TotalNumberOfLines - 1) + 1 + this.TextView.VisibleLineCount * 2 / 3) * this.TextView.FontHeight;
            }
        }
        public Point VirtualTop
        {
            get
            {
                return this.virtualTop;
            }
            set
            {
                Point right = new Point(value.X, Math.Min(this.MaxVScrollValue, Math.Max(0, value.Y)));
                if(this.virtualTop != right)
                {
                    this.virtualTop = right;
                    this.motherTextAreaControl.VScrollBar.Value = this.virtualTop.Y;
                    base.Invalidate();
                }
                this.caret.UpdateCaretPosition();
            }
        }
        public bool AutoClearSelection
        {
            get
            {
                return this.autoClearSelection;
            }
            set
            {
                this.autoClearSelection = value;
            }
        }
        [Browsable(false)]
        public IDocument Document
        {
            get
            {
                return this.motherTextEditorControl.Document;
            }
        }
        public TextAreaClipboardHandler ClipboardHandler
        {
            get
            {
                return this.textAreaClipboardHandler;
            }
        }
        public ITextEditorProperties TextEditorProperties
        {
            get
            {
                return this.motherTextEditorControl.TextEditorProperties;
            }
        }
        public bool EnableCutOrPaste
        {
            get
            {
                if(this.motherTextAreaControl == null)
                {
                    return false;
                }
                if(this.SelectionManager.HasSomethingSelected)
                {
                    return !this.SelectionManager.SelectionIsReadonly;
                }
                return !this.IsReadOnly(this.Caret.Offset);
            }
        }
        private int FirstPhysicalLine
        {
            get
            {
                return this.VirtualTop.Y / this.textView.FontHeight;
            }
        }
        public void InsertLeftMargin(int index, AbstractMargin margin)
        {
            this.leftMargins.Insert(index, margin);
            this.Refresh();
        }
        public TextArea(TextEditorControl motherTextEditorControl, TextAreaControl motherTextAreaControl)
        {
            this.motherTextAreaControl = motherTextAreaControl;
            this.motherTextEditorControl = motherTextEditorControl;
            this.caret = new Caret(this);
            this.selectionManager = new SelectionManager(this.Document, this);
            this.textAreaClipboardHandler = new TextAreaClipboardHandler(this);
            base.ResizeRedraw = true;
            base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            base.SetStyle(ControlStyles.Opaque, false);
            base.SetStyle(ControlStyles.ResizeRedraw, true);
            base.SetStyle(ControlStyles.Selectable, true);
            this.textView = new TextView(this);
            this.gutterMargin = new GutterMargin(this);
            this.foldMargin = new FoldMargin(this);
            this.iconBarMargin = new IconBarMargin(this);
            this.leftMargins.AddRange(new AbstractMargin[]
			{
				this.iconBarMargin, 
				this.gutterMargin, 
				this.foldMargin
			});
            this.OptionsChanged();
            new TextAreaMouseHandler(this).Attach();
            new TextAreaDragDropHandler().Attach(this);
            this.bracketshemes.Add(new BracketHighlightingSheme('{', '}'));
            this.bracketshemes.Add(new BracketHighlightingSheme('(', ')'));
            this.bracketshemes.Add(new BracketHighlightingSheme('[', ']'));
            this.caret.PositionChanged += new EventHandler(this.SearchMatchingBracket);
            this.Document.TextContentChanged += new EventHandler(this.TextContentChanged);
            this.Document.FoldingManager.FoldingsChanged += new EventHandler(this.DocumentFoldingsChanged);

        }
        public void UpdateMatchingBracket()
        {
            this.SearchMatchingBracket(null, null);
        }
        private void TextContentChanged(object sender, EventArgs e)
        {
            this.Caret.Position = new TextLocation(0, 0);
            this.SelectionManager.SelectionCollection.Clear();
        }
        private void SearchMatchingBracket(object sender, EventArgs e)
        {
            if(!this.TextEditorProperties.ShowMatchingBracket)
            {
                this.textView.Highlight = null;
                return;
            }
            int num = -1;
            int num2 = -1;
            if(this.textView.Highlight != null && this.textView.Highlight.OpenBrace.Y >= 0 && this.textView.Highlight.OpenBrace.Y < this.Document.TotalNumberOfLines)
            {
                num = this.textView.Highlight.OpenBrace.Y;
            }
            if(this.textView.Highlight != null && this.textView.Highlight.CloseBrace.Y >= 0 && this.textView.Highlight.CloseBrace.Y < this.Document.TotalNumberOfLines)
            {
                num2 = this.textView.Highlight.CloseBrace.Y;
            }
            this.textView.Highlight = this.FindMatchingBracketHighlight();
            if(num >= 0)
            {
                this.UpdateLine(num);
            }
            if(num2 >= 0 && num2 != num)
            {
                this.UpdateLine(num2);
            }
            if(this.textView.Highlight != null)
            {
                int y = this.textView.Highlight.OpenBrace.Y;
                int y2 = this.textView.Highlight.CloseBrace.Y;
                if(y != num && y != num2)
                {
                    this.UpdateLine(y);
                }
                if(y2 != num && y2 != num2 && y2 != y)
                {
                    this.UpdateLine(y2);
                }
            }
        }
        public Highlight FindMatchingBracketHighlight()
        {
            if(this.Caret.Offset == 0)
            {
                return null;
            }
            foreach(BracketHighlightingSheme current in this.bracketshemes)
            {
                Highlight highlight = current.GetHighlight(this.Document, this.Caret.Offset - 1);
                if(highlight != null)
                {
                    return highlight;
                }
            }
            return null;
        }
        public void SetDesiredColumn()
        {
            this.Caret.DesiredColumn = this.TextView.GetDrawingXPos(this.Caret.Line, this.Caret.Column) + this.VirtualTop.X;
        }
        public void SetCaretToDesiredColumn()
        {
            FoldMarker foldMarker;
            this.Caret.Position = this.textView.GetLogicalColumn(this.Caret.Line, this.Caret.DesiredColumn + this.VirtualTop.X, out foldMarker);
        }
        public void OptionsChanged()
        {
            this.UpdateMatchingBracket();
            this.textView.OptionsChanged();
            this.caret.RecreateCaret();
            this.caret.UpdateCaretPosition();
            this.Refresh();
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            this.Cursor = Cursors.Default;
            if(this.lastMouseInMargin != null)
            {
                this.lastMouseInMargin.HandleMouseLeave(EventArgs.Empty);
                this.lastMouseInMargin = null;
            }
            this.CloseToolTip();
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            this.mousepos = new Point(e.X, e.Y);
            base.OnMouseDown(e);
            this.CloseToolTip();
            foreach(AbstractMargin current in this.leftMargins)
            {
                if(current.DrawingPosition.Contains(e.X, e.Y))
                {
                    current.HandleMouseDown(new Point(e.X, e.Y), e.Button);
                }
            }
        }
        internal void ShowHiddenCursor(bool forceShow)
        {
            if(this.hiddenMouseCursor && (this.mouseCursorHidePosition != Cursor.Position || forceShow))
            {
                Cursor.Show();
                this.hiddenMouseCursor = false;
            }
        }
        private void SetToolTip(string text, int lineNumber)
        {
            if(TextArea.toolTip == null || TextArea.toolTip.IsDisposed)
            {
                TextArea.toolTip = new DeclarationViewWindow(base.FindForm());
            }
            if(TextArea.oldToolTip == text)
            {
                return;
            }
            if(text == null)
            {
                TextArea.toolTip.Hide();
            }
            else
            {
                Point mousePosition = Control.MousePosition;
                Point point = base.PointToClient(mousePosition);
                if(lineNumber >= 0)
                {
                    lineNumber = this.Document.GetVisibleLine(lineNumber);
                    mousePosition.Y = mousePosition.Y - point.Y + lineNumber * this.TextView.FontHeight - this.virtualTop.Y;
                }
                mousePosition.Offset(3, 3);
                TextArea.toolTip.Owner = base.FindForm();
                TextArea.toolTip.Location = mousePosition;
                TextArea.toolTip.Description = text;
                TextArea.toolTip.HideOnClick = true;
                TextArea.toolTip.Show();
            }
            TextArea.oldToolTip = text;
        }
        protected virtual void OnToolTipRequest(ToolTipRequestEventArgs e)
        {
            if(this.ToolTipRequest != null)
            {
                this.ToolTipRequest(this, e);
            }
        }
        private void CloseToolTip()
        {
            if(this.toolTipActive)
            {
                this.toolTipActive = false;
                this.SetToolTip(null, -1);
            }
            base.ResetMouseEventArgs();
        }
        protected override void OnMouseHover(EventArgs e)
        {
            base.OnMouseHover(e);
            if(Control.MouseButtons == MouseButtons.None)
            {
                this.RequestToolTip(base.PointToClient(Control.MousePosition));
                return;
            }
            this.CloseToolTip();
        }
        protected void RequestToolTip(Point mousePos)
        {
            if(this.toolTipRectangle.Contains(mousePos))
            {
                if(!this.toolTipActive)
                {
                    base.ResetMouseEventArgs();
                }
                return;
            }
            this.toolTipRectangle = new Rectangle(mousePos.X - 4, mousePos.Y - 4, 8, 8);
            TextLocation logicalPosition = this.textView.GetLogicalPosition(mousePos.X - this.textView.DrawingPosition.Left, mousePos.Y - this.textView.DrawingPosition.Top);
            bool flag = this.textView.DrawingPosition.Contains(mousePos) && logicalPosition.Y >= 0 && logicalPosition.Y < this.Document.TotalNumberOfLines;
            ToolTipRequestEventArgs toolTipRequestEventArgs = new ToolTipRequestEventArgs(mousePos, logicalPosition, flag);
            this.OnToolTipRequest(toolTipRequestEventArgs);
            if(toolTipRequestEventArgs.ToolTipShown)
            {
                this.toolTipActive = true;
                this.SetToolTip(toolTipRequestEventArgs.toolTipText, flag ? (logicalPosition.Y + 1) : -1);
                return;
            }
            this.CloseToolTip();
        }
        internal void RaiseMouseMove(MouseEventArgs e)
        {
            this.OnMouseMove(e);
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if(!this.toolTipRectangle.Contains(e.Location))
            {
                this.toolTipRectangle = Rectangle.Empty;
                if(this.toolTipActive)
                {
                    this.RequestToolTip(e.Location);
                }
            }
            foreach(AbstractMargin current in this.leftMargins)
            {
                if(current.DrawingPosition.Contains(e.X, e.Y))
                {
                    this.Cursor = current.Cursor;
                    current.HandleMouseMove(new Point(e.X, e.Y), e.Button);
                    if(this.lastMouseInMargin != current)
                    {
                        if(this.lastMouseInMargin != null)
                        {
                            this.lastMouseInMargin.HandleMouseLeave(EventArgs.Empty);
                        }
                        this.lastMouseInMargin = current;
                    }
                    return;
                }
            }
            if(this.lastMouseInMargin != null)
            {
                this.lastMouseInMargin.HandleMouseLeave(EventArgs.Empty);
                this.lastMouseInMargin = null;
            }
            if(!this.textView.DrawingPosition.Contains(e.X, e.Y))
            {
                this.Cursor = Cursors.Default;
                return;
            }
            TextLocation logicalPosition = this.TextView.GetLogicalPosition(e.X - this.TextView.DrawingPosition.X, e.Y - this.TextView.DrawingPosition.Y);
            if(this.SelectionManager.IsSelected(this.Document.PositionToOffset(logicalPosition)) && Control.MouseButtons == MouseButtons.None)
            {
                this.Cursor = Cursors.Default;
                return;
            }
            this.Cursor = this.textView.Cursor;
        }
        public void Refresh(AbstractMargin margin)
        {
            this.updateMargin = margin;
            base.Invalidate(this.updateMargin.DrawingPosition);
            base.Update();
            this.updateMargin = null;
        }
        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            int num = 0;
            int num2 = 0;
            bool flag = false;
            Graphics graphics = e.Graphics;
            Rectangle clipRectangle = e.ClipRectangle;
            bool flag2 = clipRectangle.X == 0 && clipRectangle.Y == 0 && clipRectangle.Width == base.Width && clipRectangle.Height == base.Height;
            graphics.TextRenderingHint = this.TextEditorProperties.TextRenderingHint;
            if(this.updateMargin != null)
            {
                this.updateMargin.Paint(graphics, this.updateMargin.DrawingPosition);
            }
            if(clipRectangle.Width <= 0 || clipRectangle.Height <= 0)
            {
                return;
            }
            foreach(AbstractMargin current in this.leftMargins)
            {
                if(current.IsVisible)
                {
                    Rectangle rectangle = new Rectangle(num, num2, current.Size.Width, base.Height - num2);
                    if(rectangle != current.DrawingPosition)
                    {
                        if(!flag2 && !clipRectangle.Contains(rectangle))
                        {
                            base.Invalidate();
                        }
                        flag = true;
                        current.DrawingPosition = rectangle;
                    }
                    num += current.DrawingPosition.Width;
                    if(clipRectangle.IntersectsWith(rectangle))
                    {
                        rectangle.Intersect(clipRectangle);
                        if(!rectangle.IsEmpty)
                        {
                            current.Paint(graphics, rectangle);
                        }
                    }
                }
            }
            Rectangle rectangle2 = new Rectangle(num, num2, base.Width - num, base.Height - num2);
            if(rectangle2 != this.textView.DrawingPosition)
            {
                flag = true;
                this.textView.DrawingPosition = rectangle2;
                base.BeginInvoke(new MethodInvoker(this.caret.UpdateCaretPosition));
            }
            if(clipRectangle.IntersectsWith(rectangle2))
            {
                rectangle2.Intersect(clipRectangle);
                if(!rectangle2.IsEmpty)
                {
                    this.textView.Paint(graphics, rectangle2);
                }
            }
            if(flag)
            {
                this.motherTextAreaControl.AdjustScrollBars();
            }
            base.OnPaint(e);
        }
        private void DocumentFoldingsChanged(object sender, EventArgs e)
        {
            this.Caret.UpdateCaretPosition();
            base.Invalidate();
            this.motherTextAreaControl.AdjustScrollBars();
        }
        protected internal virtual bool HandleKeyPress(char ch)
        {
            return this.KeyEventHandler != null && this.KeyEventHandler(ch);
        }
        protected override bool IsInputChar(char charCode)
        {
            return true;
        }
        internal bool IsReadOnly(int offset)
        {
            if(this.Document.ReadOnly)
            {
                return true;
            }
            if(this.TextEditorProperties.SupportReadOnlySegments)
            {
                return this.Document.MarkerStrategy.GetMarkers(offset).Exists((TextMarker m) => m.IsReadOnly);
            }
            return false;
        }
        internal bool IsReadOnly(int offset, int length)
        {
            if(this.Document.ReadOnly)
            {
                return true;
            }
            if(this.TextEditorProperties.SupportReadOnlySegments)
            {
                return this.Document.MarkerStrategy.GetMarkers(offset, length).Exists((TextMarker m) => m.IsReadOnly);
            }
            return false;
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            //TODO: Control + Left Click
            base.OnMouseClick(e);
            if(e.Button == System.Windows.Forms.MouseButtons.Left && Control.ModifierKeys == Keys.Control)
            {
                var caret = this.Caret;
                var line = this.Document.GetLineSegment(caret.Line);
                var word = line.GetWord(caret.Column);
                if(word != null)
                {
                    var wordStartOffset = word.Offset;
                    var wordEndOffset = wordStartOffset + word.Length;
                    var lineNumber = line.LineNumber;
                    this.SelectionManager.SetSelection(wordStartOffset, wordEndOffset, lineNumber);
                }
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            //TODO: Control + Enter
            if(e.Control && e.KeyCode == Keys.Enter)
            {
                var document = this.Document;
                var caret = this.Caret;
                var offset = caret.Offset;
                var column = caret.Column;
                var line = caret.Line;
                var lineSeg = document.LineSegmentCollection[line];
                var totalLength = lineSeg.TotalLength;
                var lineOffset = lineSeg.Offset;

                var text = document.GetText(lineOffset, totalLength);
                int i = 0;
                for( ; i < text.Length ; i++)
                {
                    if(text[i] != ' ') break;
                }

                this.InsertString(lineOffset, new string(' ', i) + "\n");
                caret.Position = document.OffsetToPosition(lineOffset + i);
                e.Handled = true;
                return;
            }
            base.OnKeyDown(e);
        }

        public void SimulateKeyPress(char ch)
        {
            if(this.SelectionManager.HasSomethingSelected)
            {
                if(this.SelectionManager.SelectionIsReadonly)
                {
                    return;
                }
            }
            else
            {
                if(this.IsReadOnly(this.Caret.Offset))
                {
                    return;
                }
            }
            if(ch < ' ')
            {
                return;
            }
            if(!this.hiddenMouseCursor && this.TextEditorProperties.HideMouseCursor && base.ClientRectangle.Contains(base.PointToClient(Cursor.Position)))
            {
                this.mouseCursorHidePosition = Cursor.Position;
                this.hiddenMouseCursor = true;
                Cursor.Hide();
            }
            this.CloseToolTip();
            this.BeginUpdate();
            this.Document.UndoStack.StartUndoGroup();
            try
            {
                if(!this.HandleKeyPress(ch))
                {
                    switch(this.Caret.CaretMode)
                    {
                        case CaretMode.InsertMode:
                            {
                                this.InsertChar(ch);
                                break;
                            }
                        case CaretMode.OverwriteMode:
                            {
                                this.ReplaceChar(ch);
                                break;
                            }
                    }
                }
                int line = this.Caret.Line;
                this.Document.FormattingStrategy.FormatLine(this, line, this.Document.PositionToOffset(this.Caret.Position), ch);
                this.EndUpdate();
            }
            finally
            {
                this.Document.UndoStack.EndUndoGroup();
            }
        }
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);
            this.SimulateKeyPress(e.KeyChar);
            e.Handled = true;
        }
        public bool ExecuteDialogKey(Keys keyData)
        {
            if(this.DoProcessDialogKey != null && this.DoProcessDialogKey(keyData))
            {
                return true;
            }
            IEditAction editAction = this.motherTextEditorControl.GetEditAction(keyData);
            this.AutoClearSelection = true;
            if(editAction != null)
            {
                this.BeginUpdate();
                try
                {
                    IDocument document;
                    Monitor.Enter(document = this.Document);
                    try
                    {
                        editAction.Execute(this);
                        if(this.SelectionManager.HasSomethingSelected && this.AutoClearSelection && this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal)
                        {
                            this.SelectionManager.ClearSelection();
                        }
                    }
                    finally
                    {
                        Monitor.Exit(document);
                    }
                }
                finally
                {
                    this.EndUpdate();
                    this.Caret.UpdateCaretPosition();
                }
                return true;
            }
            return false;
        }
        protected override bool ProcessDialogKey(Keys keyData)
        {
            return this.ExecuteDialogKey(keyData) || base.ProcessDialogKey(keyData);
        }
        public void ScrollToCaret()
        {
            this.motherTextAreaControl.ScrollToCaret();
        }
        public void ScrollTo(int line)
        {
            this.motherTextAreaControl.ScrollTo(line);
        }
        public void BeginUpdate()
        {
            this.motherTextEditorControl.BeginUpdate();
        }
        public void EndUpdate()
        {
            this.motherTextEditorControl.EndUpdate();
        }
        private string GenerateWhitespaceString(int length)
        {
            return new string(' ', length);
        }
        public void InsertChar(char ch)
        {
            bool isInUpdate = this.motherTextEditorControl.IsInUpdate;
            if(!isInUpdate)
            {
                this.BeginUpdate();
            }
            if(char.IsWhiteSpace(ch) && ch != '\t' && ch != '\n')
            {
                ch = ' ';
            }
            this.Document.UndoStack.StartUndoGroup();
            if(this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal && this.SelectionManager.SelectionCollection.Count > 0)
            {
                this.Caret.Position = this.SelectionManager.SelectionCollection[0].StartPosition;
                this.SelectionManager.RemoveSelectedText();
            }
            LineSegment lineSegment = this.Document.GetLineSegment(this.Caret.Line);
            int offset = this.Caret.Offset;
            int column = this.Caret.Column;
            if(lineSegment.Length < column && ch != '\n')
            {
                this.Document.Insert(offset, this.GenerateWhitespaceString(column - lineSegment.Length) + ch);
            }
            else
            {
                this.Document.Insert(offset, ch.ToString());
            }
            this.Document.UndoStack.EndUndoGroup();
            this.Caret.Column++;
            if(!isInUpdate)
            {
                this.EndUpdate();
                this.UpdateLineToEnd(this.Caret.Line, this.Caret.Column);
            }
        }

        public void InsertString(int offset, string str)
        {
            if(string.IsNullOrEmpty(str)) return;
            bool isInUpdate = this.motherTextEditorControl.IsInUpdate;
            if(!isInUpdate)
            {
                this.BeginUpdate();
            }
            try
            {
                this.Document.UndoStack.StartUndoGroup();
                if(this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal && this.SelectionManager.SelectionCollection.Count > 0)
                {
                    this.SelectionManager.ClearSelection();
                }
                var postion = this.Document.OffsetToPosition(offset);
                int line = postion.Line;
                LineSegment lineSegment = this.Document.GetLineSegment(postion.Line);
                if(lineSegment.Length < this.Caret.Column)
                {
                    int num2 = postion.Column - lineSegment.Length;
                    this.Document.Insert(offset, this.GenerateWhitespaceString(num2) + str);
                    this.Caret.Position = this.Document.OffsetToPosition(offset + str.Length + num2);
                }
                else
                {
                    this.Document.Insert(offset, str);
                    this.Caret.Position = this.Document.OffsetToPosition(offset + str.Length);
                }
                this.Document.UndoStack.EndUndoGroup();
                if(line != this.Caret.Line)
                {
                    this.UpdateToEnd(line);
                }
                else
                {
                    this.UpdateLineToEnd(postion.Line, postion.Column);
                }
            }
            finally
            {
                if(!isInUpdate)
                {
                    this.EndUpdate();
                }
            }
        }
        public void InsertString(string str)
        {
            this.InsertString(this.Caret.Offset, str);
            //bool isInUpdate = this.motherTextEditorControl.IsInUpdate;
            //if(!isInUpdate)
            //{
            //    this.BeginUpdate();
            //}
            //try
            //{
            //    this.Document.UndoStack.StartUndoGroup();
            //    if(this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal && this.SelectionManager.SelectionCollection.Count > 0)
            //    {
            //        this.Caret.Position = this.SelectionManager.SelectionCollection[0].StartPosition;
            //        this.SelectionManager.RemoveSelectedText();
            //    }
            //    int num = this.Document.PositionToOffset(this.Caret.Position);
            //    int line = this.Caret.Line;
            //    LineSegment lineSegment = this.Document.GetLineSegment(this.Caret.Line);
            //    if(lineSegment.Length < this.Caret.Column)
            //    {
            //        int num2 = this.Caret.Column - lineSegment.Length;
            //        this.Document.Insert(num, this.GenerateWhitespaceString(num2) + str);
            //        this.Caret.Position = this.Document.OffsetToPosition(num + str.Length + num2);
            //    }
            //    else
            //    {
            //        this.Document.Insert(num, str);
            //        this.Caret.Position = this.Document.OffsetToPosition(num + str.Length);
            //    }
            //    this.Document.UndoStack.EndUndoGroup();
            //    if(line != this.Caret.Line)
            //    {
            //        this.UpdateToEnd(line);
            //    }
            //    else
            //    {
            //        this.UpdateLineToEnd(this.Caret.Line, this.Caret.Column);
            //    }
            //}
            //finally
            //{
            //    if(!isInUpdate)
            //    {
            //        this.EndUpdate();
            //    }
            //}
        }
        public void ReplaceChar(char ch)
        {
            bool isInUpdate = this.motherTextEditorControl.IsInUpdate;
            if(!isInUpdate)
            {
                this.BeginUpdate();
            }
            if(this.Document.TextEditorProperties.DocumentSelectionMode == DocumentSelectionMode.Normal && this.SelectionManager.SelectionCollection.Count > 0)
            {
                this.Caret.Position = this.SelectionManager.SelectionCollection[0].StartPosition;
                this.SelectionManager.RemoveSelectedText();
            }
            int line = this.Caret.Line;
            LineSegment lineSegment = this.Document.GetLineSegment(line);
            int num = this.Document.PositionToOffset(this.Caret.Position);
            if(num < lineSegment.Offset + lineSegment.Length)
            {
                this.Document.Replace(num, 1, ch.ToString());
            }
            else
            {
                this.Document.Insert(num, ch.ToString());
            }
            if(!isInUpdate)
            {
                this.EndUpdate();
                this.UpdateLineToEnd(line, this.Caret.Column);
            }
            this.Caret.Column++;
        }
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if(disposing && !this.disposed)
            {
                this.disposed = true;
                if(this.caret != null)
                {
                    this.caret.PositionChanged -= new EventHandler(this.SearchMatchingBracket);
                    this.caret.Dispose();
                }
                if(this.selectionManager != null)
                {
                    this.selectionManager.Dispose();
                }
                this.Document.TextContentChanged -= new EventHandler(this.TextContentChanged);
                this.Document.FoldingManager.FoldingsChanged -= new EventHandler(this.DocumentFoldingsChanged);
                this.motherTextAreaControl = null;
                this.motherTextEditorControl = null;
                foreach(AbstractMargin current in this.leftMargins)
                {
                    if(current is IDisposable)
                    {
                        (current as IDisposable).Dispose();
                    }
                }
                this.textView.Dispose();
            }
        }
        internal void UpdateLine(int line)
        {
            this.UpdateLines(0, line, line);
        }
        internal void UpdateLines(int lineBegin, int lineEnd)
        {
            this.UpdateLines(0, lineBegin, lineEnd);
        }
        internal void UpdateToEnd(int lineBegin)
        {
            lineBegin = this.Document.GetVisibleLine(lineBegin);
            int num = Math.Max(0, lineBegin * this.textView.FontHeight);
            num = Math.Max(0, num - this.virtualTop.Y);
            Rectangle rc = new Rectangle(0, num, base.Width, base.Height - num);
            base.Invalidate(rc);
        }
        internal void UpdateLineToEnd(int lineNr, int xStart)
        {
            this.UpdateLines(xStart, lineNr, lineNr);
        }
        internal void UpdateLine(int line, int begin, int end)
        {
            this.UpdateLines(line, line);
        }
        internal void UpdateLines(int xPos, int lineBegin, int lineEnd)
        {
            this.InvalidateLines(xPos * this.TextView.WideSpaceWidth, lineBegin, lineEnd);
        }
        private void InvalidateLines(int xPos, int lineBegin, int lineEnd)
        {
            lineBegin = Math.Max(this.Document.GetVisibleLine(lineBegin), this.FirstPhysicalLine);
            lineEnd = Math.Min(this.Document.GetVisibleLine(lineEnd), this.FirstPhysicalLine + this.textView.VisibleLineCount);
            int num = Math.Max(0, lineBegin * this.textView.FontHeight);
            int num2 = Math.Min(this.textView.DrawingPosition.Height, (1 + lineEnd - lineBegin) * (this.textView.FontHeight + 1));
            Rectangle rc = new Rectangle(0, num - 1 - this.virtualTop.Y, base.Width, num2 + 3);
            base.Invalidate(rc);
        }
    }
}
